﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows.Forms;
using System.Collections;

namespace AbyssCombatLogger
{
    public class ScriptReporter : Form
    {
        //line breaks use: <br />
        private string lastReportHTMLForBrowser = null;
        private string lastReportHTMLForScript = null;
        private string player = "Player";
        private string linkText = "ACL - Report";
        public string ChatChannel
        {
            get { return cbChatChannel.Text; }
        }
        public const string def_Template = "/{CHANNEL} " + "{PREFIX} <a href=\"text://{CONTENT}{POSTFIX}\">{LINKTEXT}</a>";

        public const string def_Preview_Template = "<html> <head> <title> ACL - Report </title> </head><body>{PREFIX}{CONTENT}{POSTFIX}</body></html>";
        public const string def_Centered_Header = "<div align=center><font color=#660000>{HEADERTEXT}</font></div>";
        //public const string sHeader = "ACL - Stats - {HEADERTEXT}<br />";
        public string def_AfterHeader;

        //<font color=#ffff00>
        //<td><font color=#ffffff>{TARGET}</font></td>
        public const string def_RowOfData = "<tt>{RANK}" + "{TARGET}"
                                                + "<font color=#ff0000>{DAMAGE}</font>"
                                                + "<font color=#00FF00>{HEALING}</font></tt><br />";
        private const string def_AfterData = "";
        private string Game_Path = null;
        public const string scriptRelativeToGamePath = "scripts\\";
        private string scriptReportTemplatePath = null;
        private string scriptReportTemplateFile = "report-template.txt";
        public const string scriptFileName = "report"; //dont put an extension the file.. aoc likes it that way
        private string scriptTemplate = null;

        public const string logOnAndOffScriptFileName = "acl";
        private MenuStrip menuStrip1;
        public const string logOnAndOffScriptContents = "/logcombat on";
        private ToolStripMenuItem generatereportScriptToolStripMenuItem;
        private TabControl tcPages;
        private TabPage tpView;
        private TabPage tpModify;
        private TextBox tbPostBody;
        private TextBox tbCenteredHeader;
        private TabPage tpHTML;
        private TextBox tbHTMLView;
        private Label label3;
        private Label label2;
        private Label lblCenteredHeader;
        private TextBox tbPrefix;
        private Label lblPrefix;
        private WebBrowser wbReportViewer;
        private Label lblChatTarget;
        private ComboBox cbChatChannel;
        private TextBox tbDataRow;

        EventHandlers requiredData = null;
        
        public static bool CreateALogCombatScript(string fullPath)
        {
            StreamWriter writer = null;
            bool status = false;
            try{
                writer = new StreamWriter(fullPath);
                
                writer.WriteLine(logOnAndOffScriptContents);
                writer.Flush();
                status = true;
            }
            catch (Exception exIO)
            {
                status = false;
            }
            finally
            {
                if (writer !=null) writer.Close();
            }
            return status;
        }
        public string Player
        {
            get { return player; }
            set { if (player !=null && player.Trim() !="")
                player = value; }
        }

        public ScriptReporter(string aocPath, string playerName, ref EventHandlers requiredData)
        {
            SetGameScriptPath(aocPath);
            SetScriptTemplatePathToDefault();
            this.Player = playerName;
            this.requiredData = requiredData;

            InitializeComponent();
            this.cbChatChannel.Text = "raid";
            this.def_AfterHeader = "<tt>" + PadWord("Rank", 5) + PadWord("Player", 18) + PadWord("Damage", 12) + "Healing"+ "</tt><br />";

            this.tbDataRow.Text = def_RowOfData;
            this.tbCenteredHeader.Text = def_Centered_Header;
            this.tbPostBody.Text = "";
            this.tbPrefix.Text = "";
            //ReadTemplateFromFile();

        }

        private void SetScriptTemplatePathToDefault()
        {
            scriptReportTemplatePath = Application.ExecutablePath.Substring(0, Application.ExecutablePath.LastIndexOf("\\") + 1);
        }
        private bool SetGameScriptPath(string gamePath)
        {
            if (gamePath != null && gamePath != "" && gamePath.Trim().Length > 0)
            {
                if (!gamePath.Trim().EndsWith("\\"))
                    gamePath = gamePath + "\\";
                Game_Path = gamePath;
                return true;
            }
            else return false;
        }


        public Hashtable GetCombinedStats(ref Hashtable damageDoneHash, ref Hashtable healingDoneHash)
        {
            Hashtable combined = new Hashtable();
            foreach (string dmgDoer in damageDoneHash.Keys)
            {
                if (dmgDoer != null && dmgDoer != "" && !dmgDoer.Contains(" "))
                {
                    long damageDone = (long)damageDoneHash[dmgDoer];
                    if (!combined.ContainsKey(dmgDoer))
                    {
                        Stat theStat = new Stat(dmgDoer, damageDone, 0);
                        combined.Add(dmgDoer, theStat);
                    }
                }
            }

            foreach (string healer in healingDoneHash.Keys)
            {
                if (healer != null && healer != "" && !healer.Contains(" "))
                {
                    long healingDone = (long)healingDoneHash[healer];
                    if (!combined.ContainsKey(healer))
                    {
                        Stat theStat = new Stat(healer, 0, healingDone);
                        combined.Add(healer, theStat);
                    }
                    else
                    {
                        ((Stat)(combined[healer])).Healing = healingDone;
                    }
                }
            }

            return combined;
        }
        public bool WriteReportToScriptFile(ref Hashtable damageDoneHash, ref Hashtable healingDoneHash)
        {
            string fullPath = FullScriptPath;
            string report = GetReportString(ref damageDoneHash, ref healingDoneHash);

            try
            {
                try
                {
                    if (File.Exists(fullPath))
                        File.Delete(fullPath);//delete so user doesnt accidentally post old info.
                }
                catch (Exception deleteFileError)
                {
                }

                if (report != null && report != "")
                {
                    StreamWriter writer = new StreamWriter(fullPath);
                    writer.Write(report);
                    writer.Flush();
                    writer.Close();
                    return true;
                }
                else return false;
            } catch(Exception exIO)
            {
                return false;
            }
        }

        private StatComparer defaultStatComparer = new StatComparer(StatType.Damage);


        public string GetReportString(ref Hashtable damageDoneHash, ref Hashtable healingDoneHash)
        {
            StringBuilder contentBuffer = new StringBuilder();

            string header = tbCenteredHeader.Text.Replace("{HEADERTEXT}",  DateTime.Now.ToLocalTime() + " " + TimeZone.CurrentTimeZone.StandardName );

            contentBuffer.Append(header);
            contentBuffer.Append(def_AfterHeader);


            //do table
            Hashtable combinedStats = GetCombinedStats(ref damageDoneHash, ref healingDoneHash);

            //List<string> rowsOfText = new List<string>();

            if (combinedStats == null || combinedStats.Count == 0)
                return null;

            List<Stat> lsSorted =  new List<Stat>();
            
            foreach (string player in combinedStats.Keys)
            {
                Stat playerStat = (Stat)combinedStats[player];
                lsSorted.Add(playerStat);
            }
            lsSorted.Sort(defaultStatComparer);


            int rank = 0;
            foreach (Stat stat in lsSorted)
            {
                string theRealPlayer = stat.Target;

                if (!theRealPlayer.Contains("'") && !theRealPlayer.Contains(" ") && !theRealPlayer.Contains("-")) //for now dont add garbage data
                {
                    if (theRealPlayer == "You")
                        theRealPlayer = this.Player;

                    rank++;

                    if (stat != null)
                    {
                        //THIS WAS MODIFIED as the values were being modified by adding horrible looking period marks.
                        string rowOfData = tbDataRow.Text.Replace("{RANK}", rank.ToString());
                        rowOfData = rowOfData.Replace("{TARGET}", theRealPlayer);
                        rowOfData = rowOfData.Replace("{DAMAGE}", stat.Damage.ToString());
                        rowOfData = rowOfData.Replace("{HEALING}", stat.Healing.ToString());
                        
                        contentBuffer.Append(rowOfData);
                    }
                }
            }
            contentBuffer.Append(def_AfterData); //</table>
            //contentBuffer.Append(tbPostBody.Text);
            //end body

            string scriptContent = def_Template
                .Replace("{PREFIX}", tbPrefix.Text)
                .Replace("{CONTENT}", contentBuffer.ToString())
                .Replace("{POSTFIX}", tbPostBody.Text)
                .Replace("{LINKTEXT}", linkText)
                .Replace("{CHANNEL}", ChatChannel);
          
            lastReportHTMLForBrowser = def_Preview_Template
                .Replace("{PREFIX}", tbPrefix.Text)
                .Replace("{CONTENT}", contentBuffer.ToString())
                .Replace("{POSTFIX}", tbPostBody.Text);

            lastReportHTMLForScript = scriptContent;
            return scriptContent;
        }

        private string PadWord(object o, int p_2)
        {
            string toStringOfO = o.ToString(); 
            int sLen = toStringOfO.Length;
            string space = ".";// "&nbsp;";
            int numSpaces = p_2 - sLen;
            if (o.GetType() == typeof(long))
            {
                //pad on left                
                string final = toStringOfO;
                for (int i = 1; i <= numSpaces; i++)
                {
                    final = space + final;
                }
                return final;
            }
            else
            {
                string final = toStringOfO;
                for (int i = 1; i <= numSpaces; i++)
                {
                    final = final + space;
                }
                return final;
            }
        }

        public bool ReadTemplateFromFile()
        {
            string fullPath = FullTemplatePath;
            if (File.Exists(fullPath))
            {
                StreamReader fileReader = new StreamReader(fullPath) ;
                //read its contents
                scriptTemplate = fileReader.ReadToEnd();
                fileReader.Close();
                return true;
            }
            else
                return false;
        }
        public string FullTemplatePath
        {
            get
            {
                return scriptReportTemplatePath + scriptReportTemplateFile;
            }
        }
        public string FullGameScriptPath
        {
            get
            {
                return Game_Path + scriptRelativeToGamePath;
            }
        }


        public string FullScriptPath { 
            get {
                return FullGameScriptPath + scriptFileName;
            } 
        }

        private void InitializeComponent()
        {
            this.menuStrip1 = new System.Windows.Forms.MenuStrip();
            this.generatereportScriptToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            this.tcPages = new System.Windows.Forms.TabControl();
            this.tpView = new System.Windows.Forms.TabPage();
            this.wbReportViewer = new System.Windows.Forms.WebBrowser();
            this.tpModify = new System.Windows.Forms.TabPage();
            this.tbDataRow = new System.Windows.Forms.TextBox();
            this.lblChatTarget = new System.Windows.Forms.Label();
            this.cbChatChannel = new System.Windows.Forms.ComboBox();
            this.tbPrefix = new System.Windows.Forms.TextBox();
            this.lblPrefix = new System.Windows.Forms.Label();
            this.label3 = new System.Windows.Forms.Label();
            this.label2 = new System.Windows.Forms.Label();
            this.lblCenteredHeader = new System.Windows.Forms.Label();
            this.tbPostBody = new System.Windows.Forms.TextBox();
            this.tbCenteredHeader = new System.Windows.Forms.TextBox();
            this.tpHTML = new System.Windows.Forms.TabPage();
            this.tbHTMLView = new System.Windows.Forms.TextBox();
            this.menuStrip1.SuspendLayout();
            this.tcPages.SuspendLayout();
            this.tpView.SuspendLayout();
            this.tpModify.SuspendLayout();
            this.tpHTML.SuspendLayout();
            this.SuspendLayout();
            // 
            // menuStrip1
            // 
            this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
            this.generatereportScriptToolStripMenuItem});
            this.menuStrip1.Location = new System.Drawing.Point(0, 0);
            this.menuStrip1.Name = "menuStrip1";
            this.menuStrip1.Size = new System.Drawing.Size(554, 28);
            this.menuStrip1.TabIndex = 1;
            this.menuStrip1.Text = "menuStrip1";
            // 
            // generatereportScriptToolStripMenuItem
            // 
            this.generatereportScriptToolStripMenuItem.Name = "generatereportScriptToolStripMenuItem";
            this.generatereportScriptToolStripMenuItem.Size = new System.Drawing.Size(174, 24);
            this.generatereportScriptToolStripMenuItem.Text = "Generate /report Script";
            this.generatereportScriptToolStripMenuItem.Click += new System.EventHandler(this.generatereportScriptToolStripMenuItem_Click);
            // 
            // tcPages
            // 
            this.tcPages.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
                        | System.Windows.Forms.AnchorStyles.Left)
                        | System.Windows.Forms.AnchorStyles.Right)));
            this.tcPages.Controls.Add(this.tpView);
            this.tcPages.Controls.Add(this.tpModify);
            this.tcPages.Controls.Add(this.tpHTML);
            this.tcPages.Location = new System.Drawing.Point(0, 35);
            this.tcPages.Name = "tcPages";
            this.tcPages.SelectedIndex = 0;
            this.tcPages.Size = new System.Drawing.Size(554, 305);
            this.tcPages.TabIndex = 2;
            // 
            // tpView
            // 
            this.tpView.Controls.Add(this.wbReportViewer);
            this.tpView.Location = new System.Drawing.Point(4, 25);
            this.tpView.Name = "tpView";
            this.tpView.Padding = new System.Windows.Forms.Padding(3);
            this.tpView.Size = new System.Drawing.Size(546, 276);
            this.tpView.TabIndex = 0;
            this.tpView.Text = "View";
            // 
            // wbReportViewer
            // 
            this.wbReportViewer.AllowNavigation = false;
            this.wbReportViewer.Dock = System.Windows.Forms.DockStyle.Fill;
            this.wbReportViewer.Location = new System.Drawing.Point(3, 3);
            this.wbReportViewer.MinimumSize = new System.Drawing.Size(20, 20);
            this.wbReportViewer.Name = "wbReportViewer";
            this.wbReportViewer.Size = new System.Drawing.Size(540, 270);
            this.wbReportViewer.TabIndex = 0;
            // 
            // tpModify
            // 
            this.tpModify.Controls.Add(this.tbDataRow);
            this.tpModify.Controls.Add(this.lblChatTarget);
            this.tpModify.Controls.Add(this.cbChatChannel);
            this.tpModify.Controls.Add(this.tbPrefix);
            this.tpModify.Controls.Add(this.lblPrefix);
            this.tpModify.Controls.Add(this.label3);
            this.tpModify.Controls.Add(this.label2);
            this.tpModify.Controls.Add(this.lblCenteredHeader);
            this.tpModify.Controls.Add(this.tbPostBody);
            this.tpModify.Controls.Add(this.tbCenteredHeader);
            this.tpModify.Location = new System.Drawing.Point(4, 25);
            this.tpModify.Name = "tpModify";
            this.tpModify.Padding = new System.Windows.Forms.Padding(3);
            this.tpModify.Size = new System.Drawing.Size(546, 276);
            this.tpModify.TabIndex = 1;
            this.tpModify.Text = "Modify Script";
            this.tpModify.UseVisualStyleBackColor = true;
            // 
            // tbDataRow
            // 
            this.tbDataRow.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
                        | System.Windows.Forms.AnchorStyles.Right)));
            this.tbDataRow.Location = new System.Drawing.Point(6, 181);
            this.tbDataRow.Name = "tbDataRow";
            this.tbDataRow.Size = new System.Drawing.Size(531, 22);
            this.tbDataRow.TabIndex = 11;
            // 
            // lblChatTarget
            // 
            this.lblChatTarget.AutoSize = true;
            this.lblChatTarget.Location = new System.Drawing.Point(8, 9);
            this.lblChatTarget.Name = "lblChatTarget";
            this.lblChatTarget.Size = new System.Drawing.Size(87, 17);
            this.lblChatTarget.TabIndex = 10;
            this.lblChatTarget.Text = "Chat Target:";
            // 
            // cbChatChannel
            // 
            this.cbChatChannel.FormattingEnabled = true;
            this.cbChatChannel.Items.AddRange(new object[] {
            "group",
            "guild",
            "raid",
            "say",
            "tell %t"});
            this.cbChatChannel.Location = new System.Drawing.Point(120, 9);
            this.cbChatChannel.Name = "cbChatChannel";
            this.cbChatChannel.Size = new System.Drawing.Size(412, 24);
            this.cbChatChannel.TabIndex = 9;
            // 
            // tbPrefix
            // 
            this.tbPrefix.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
                        | System.Windows.Forms.AnchorStyles.Right)));
            this.tbPrefix.Location = new System.Drawing.Point(6, 61);
            this.tbPrefix.Multiline = true;
            this.tbPrefix.Name = "tbPrefix";
            this.tbPrefix.Size = new System.Drawing.Size(528, 22);
            this.tbPrefix.TabIndex = 8;
            // 
            // lblPrefix
            // 
            this.lblPrefix.AutoSize = true;
            this.lblPrefix.Location = new System.Drawing.Point(8, 41);
            this.lblPrefix.Name = "lblPrefix";
            this.lblPrefix.Size = new System.Drawing.Size(43, 17);
            this.lblPrefix.TabIndex = 7;
            this.lblPrefix.Text = "Prefix";
            // 
            // label3
            // 
            this.label3.AutoSize = true;
            this.label3.Location = new System.Drawing.Point(0, 214);
            this.label3.Name = "label3";
            this.label3.Size = new System.Drawing.Size(72, 17);
            this.label3.TabIndex = 6;
            this.label3.Text = "Post Body";
            // 
            // label2
            // 
            this.label2.AutoSize = true;
            this.label2.Location = new System.Drawing.Point(0, 150);
            this.label2.Name = "label2";
            this.label2.Size = new System.Drawing.Size(69, 17);
            this.label2.TabIndex = 5;
            this.label2.Text = "Data Row";
            // 
            // lblCenteredHeader
            // 
            this.lblCenteredHeader.AutoSize = true;
            this.lblCenteredHeader.Location = new System.Drawing.Point(3, 91);
            this.lblCenteredHeader.Name = "lblCenteredHeader";
            this.lblCenteredHeader.Size = new System.Drawing.Size(117, 17);
            this.lblCenteredHeader.TabIndex = 4;
            this.lblCenteredHeader.Text = "Centered Header";
            // 
            // tbPostBody
            // 
            this.tbPostBody.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
                        | System.Windows.Forms.AnchorStyles.Left)
                        | System.Windows.Forms.AnchorStyles.Right)));
            this.tbPostBody.Location = new System.Drawing.Point(4, 234);
            this.tbPostBody.Multiline = true;
            this.tbPostBody.Name = "tbPostBody";
            this.tbPostBody.Size = new System.Drawing.Size(534, 36);
            this.tbPostBody.TabIndex = 2;
            // 
            // tbCenteredHeader
            // 
            this.tbCenteredHeader.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
                        | System.Windows.Forms.AnchorStyles.Right)));
            this.tbCenteredHeader.Location = new System.Drawing.Point(6, 111);
            this.tbCenteredHeader.Multiline = true;
            this.tbCenteredHeader.Name = "tbCenteredHeader";
            this.tbCenteredHeader.Size = new System.Drawing.Size(531, 36);
            this.tbCenteredHeader.TabIndex = 0;
            // 
            // tpHTML
            // 
            this.tpHTML.Controls.Add(this.tbHTMLView);
            this.tpHTML.Location = new System.Drawing.Point(4, 25);
            this.tpHTML.Name = "tpHTML";
            this.tpHTML.Size = new System.Drawing.Size(546, 276);
            this.tpHTML.TabIndex = 2;
            this.tpHTML.Text = "HTML";
            this.tpHTML.UseVisualStyleBackColor = true;
            // 
            // tbHTMLView
            // 
            this.tbHTMLView.Dock = System.Windows.Forms.DockStyle.Fill;
            this.tbHTMLView.Location = new System.Drawing.Point(0, 0);
            this.tbHTMLView.Multiline = true;
            this.tbHTMLView.Name = "tbHTMLView";
            this.tbHTMLView.Size = new System.Drawing.Size(546, 327);
            this.tbHTMLView.TabIndex = 3;
            // 
            // ScriptReporter
            // 
            this.ClientSize = new System.Drawing.Size(554, 335);
            this.Controls.Add(this.tcPages);
            this.Controls.Add(this.menuStrip1);
            this.MainMenuStrip = this.menuStrip1;
            this.Name = "ScriptReporter";
            this.Text = "/report";
            this.menuStrip1.ResumeLayout(false);
            this.menuStrip1.PerformLayout();
            this.tcPages.ResumeLayout(false);
            this.tpView.ResumeLayout(false);
            this.tpModify.ResumeLayout(false);
            this.tpModify.PerformLayout();
            this.tpHTML.ResumeLayout(false);
            this.tpHTML.PerformLayout();
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        private void generatereportScriptToolStripMenuItem_Click(object sender, EventArgs e)
        {
            WriteReportToScriptFile(ref requiredData.htTotalDamagesByPlayer, ref requiredData.htTotalHealsByPlayer);
            //SimpleMessage("Report created. Type /report in game to post your report.");
            wbReportViewer.DocumentText = lastReportHTMLForBrowser;
            tbHTMLView.Text = lastReportHTMLForScript;
            wbReportViewer.Update();
        }
    }
}
